package org.kgduyjj.toolbox;

import java.io.UnsupportedEncodingException;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

/**
 * 加密解密工具
 * 
 * @author Kgduyjj
 * @since 2018-08-30
 * @version Alpha-1.42
 *
 */
@SuppressWarnings("restriction")
public class SecretUtil {
	/** 默认加密密钥 **/
	public static final String DEFAULT_CIPHER_KEY = "b4476ff65dcecb02f39e7d22eb8b30b6";
	/** 算法 **/
	private static final String CIPHER_TYPE = "DESede";
	/** 默认编码格式 **/
	private static final String DEFAULT_ENCODE = "UTF-8";

	/**
	 * 加密模式
	 * 
	 * @param bytes
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unused")
	private static byte[] encryptMode(byte[] bytes) throws Exception {
		return encryptMode(bytes, DEFAULT_CIPHER_KEY);
	}

	/**
	 * 加密模式
	 * 
	 * @param bytes
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unused")
	private static String encryptModeString(byte[] bytes) throws Exception {
		return Base64.encode(encryptMode(bytes, DEFAULT_CIPHER_KEY));
	}

	/**
	 * 加密模式
	 * 
	 * @param bytes
	 * @param key
	 * @return
	 * @throws Exception
	 */
	private static String encryptModeString(byte[] bytes, String key) throws Exception {
		return Base64.encode(encryptMode(bytes, key));
	}

	/**
	 * 加密模式
	 * 
	 * @param bytes
	 * @param key
	 * @return
	 * @throws Exception
	 */
	private static byte[] encryptMode(byte[] bytes, String key) throws Exception {
		SecretKey deskey = new SecretKeySpec(build3DesKey(key), CIPHER_TYPE);
		Cipher c1 = Cipher.getInstance(CIPHER_TYPE);
		c1.init(1, deskey);
		return c1.doFinal(bytes);
	}

	/**
	 * 解密模式
	 * 
	 * @param bytes
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unused")
	private static byte[] decryptMode(byte[] bytes) throws Exception {
		return decryptMode(bytes, DEFAULT_CIPHER_KEY);
	}

	/**
	 * 解密模式
	 * 
	 * @param content
	 * @param key
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unused")
	private static String decryptMode(String content, String key) throws Exception {
		return new String(decryptMode(Base64.decode(content), key), DEFAULT_ENCODE);
	}

	/**
	 * 解密模式
	 * 
	 * @param content
	 * @param key
	 * @param encode
	 * @return
	 * @throws Exception
	 */
	private static String decryptMode(String content, String key, String encode) throws Exception {
		return new String(decryptMode(Base64.decode(content), key), encode);
	}

	/**
	 * 加密模式
	 * 
	 * @param content
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unused")
	private static String decryptMode(String content) throws Exception {
		return new String(decryptMode(Base64.decode(content), DEFAULT_CIPHER_KEY));
	}

	/**
	 * 加密模式
	 * 
	 * @param bytes
	 * @param key
	 * @return
	 * @throws Exception
	 */
	private static byte[] decryptMode(byte[] bytes, String key) throws Exception {
		SecretKey deskey = new SecretKeySpec(build3DesKey(key), CIPHER_TYPE);
		Cipher c1 = Cipher.getInstance(CIPHER_TYPE);
		c1.init(2, deskey);
		return c1.doFinal(bytes);
	}

	/**
	 * 构建3DesKey
	 * 
	 * @param keyStr
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	private static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException {
		byte[] key = new byte[24];
		byte[] temp = keyStr.getBytes(DEFAULT_ENCODE);

		if (key.length > temp.length) {
			System.arraycopy(temp, 0, key, 0, temp.length);
		} else
			System.arraycopy(temp, 0, key, 0, key.length);

		return key;
	}

	/**
	 * 加密字节组（加密方案为UTF-8）
	 * 
	 * @param text
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String encrypt(byte[] bytes, String key) throws Exception {
		if ((bytes == null) || bytes.length == 0)
			return null;
		return encryptModeString(bytes, _checkPrivateKey(key));
	}

	/**
	 * 加密文本内容
	 * 
	 * @param text
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String encrypt(String text, String key) throws Exception {
		if ((text == null) || (text.length() == 0))
			return null;
		return encryptModeString(text.getBytes(), _checkPrivateKey(key));
	}

	/**
	 * 解密字节组（解密方案为UTF-8）
	 * 
	 * @param text
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String decrypt(byte[] bytes, String key) throws Exception {
		if ((bytes == null) || bytes.length == 0)
			return null;
		_checkPrivateKey(key);
		return decryptMode(new String(bytes, DEFAULT_ENCODE), _checkPrivateKey(key), DEFAULT_ENCODE);
	}

	/**
	 * 解密文本内容
	 * 
	 * @param text
	 * @param key
	 * @param encode
	 * @return
	 * @throws Exception
	 */
	public static String decrypt(String text, String key) throws Exception {
		if ((text == null) || (text.length() == 0))
			return null;

		return decryptMode(text, _checkPrivateKey(key), DEFAULT_ENCODE);
	}

	private static String _checkPrivateKey(String key) {
		if ((key == null) || (key.length() == 0))
			return DEFAULT_CIPHER_KEY;
		return key;
	}
}
